package com.heima.wemedia.service.impl;

import com.alibaba.fastjson.JSON;
import com.heima.common.dtos.ResponseResult;
import com.heima.common.enums.TaskTypeEnum;
import com.heima.feign.clients.ScheduleClient;
import com.heima.schedule.dto.Task;
import com.heima.utils.common.ProtostuffUtil;
import com.heima.wemedia.pojo.WmNews;
import com.heima.wemedia.service.WmNewsAutoScanService;
import com.heima.wemedia.service.WmNewsTaskService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import java.util.Date;

@Service
@Slf4j
public class WmNewsTaskServiceImpl implements WmNewsTaskService {

    @Autowired
    public ScheduleClient scheduleClient;

    @Autowired
    private WmNewsAutoScanService wmNewsAutoScanService;

    /**
     * @param wmId        文章Id
     * @param publishTime 发布的时间，就是任务的消费时间
     */
    @Override
    @Async
    public void addNews2Task(Integer wmId, Date publishTime) {

        log.info("添加任务到延迟队列");

        Task task = new Task();
        task.setExecuteTime(publishTime.getTime());
        task.setTaskType(TaskTypeEnum.NEWS_SCAN_TIME.getTaskType());
        task.setPriority(TaskTypeEnum.REMOTEERROR.getPriority());
        //对parameter赋值，只需将wmid存入即可，若后面需要详细信息，就获取到wmId再查询
        WmNews wmNews = new WmNews();
        wmNews.setId(wmId);
        //将wmId存进wmnew对象中，并且需要序列化
        task.setParameters(ProtostuffUtil.serialize(wmNews));

        scheduleClient.saveTask(task);

        log.info("任务已添加完成");
    }


    /**
     * 消费任务，在redis的list里，该方法无需调用，但是每秒钟自动执行拉取任务
     */
    @Scheduled(fixedRate = 1000) //毫秒
    @Override
    public void pullNewsFromRedis() {

        log.info("消费任务，存储Article...");

        //获取任务的key，就是list队列的key，消费只在list端执行
        //这里有type, priority，就能拿到key(由它俩组成)，并且调用feign拉取任务
        ResponseResult responseResult = scheduleClient.pullTask(TaskTypeEnum.NEWS_SCAN_TIME.getTaskType(), TaskTypeEnum.REMOTEERROR.getPriority());

        //对结果响应判断
        if (responseResult.getCode().equals(200) && responseResult.getData() != null) {

            //因为public T getData() { return data; }泛型为T。而我们要得到task对象，所以先转为json，在反序列化为task对象
            Task task = JSON.parseObject(JSON.toJSONString(responseResult.getData()), Task.class);

            //得到task对象，获取parameter里的wmNews对象，该对象里只存了一个wmNewsId
            WmNews wmNews = ProtostuffUtil.deserialize(task.getParameters(), WmNews.class); //反序列化

            //得到wmNewsId放到save2Article方法，将文章写进Article表，配置表，详情表，操作三张表
            Integer wmNewsId = wmNews.getId();
            wmNewsAutoScanService.save2Article(wmNewsId);

        }

    }
}
